﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cilada.engine;
using cilada.engine.Graph;
using System.IO;
using QuickGraph;
using NUnit.Framework;

namespace cilada.Tests
{
    public class TestUtils
    {
        public const string TestLibNamespace = "cilada.TestLib";

        private static QuickGraphAdapter<IMember, TaggedEdge<IMember, EdgeType>> _testLibGraph = null;
        public static QuickGraphAdapter<IMember, TaggedEdge<IMember, EdgeType>> TestLibGraph
        {
            get
            {
                if (_testLibGraph == null)
                {
                    _testLibGraph = LoadTestGraph();
                }
                return _testLibGraph;
            }
        }

        public static string GenerateTestLibAbsolutePath()
        {
            string relativePath = String.Join(Path.DirectorySeparatorChar.ToString(), new string[] { "..", "..", "..", "cilada.TestLib", "bin", "Debug", "cilada.TestLib.dll" });
            string absolutePath = Path.GetFullPath(relativePath);
            Console.WriteLine("Absolute path to cilada.TestLib.dll is " + absolutePath);
            if (!File.Exists(absolutePath))
            {
                throw new FileNotFoundException("Could not find cilada.TestLib.dll at "+absolutePath+". You may need to compile it.");
            }

            return absolutePath;
        }

        public static QuickGraphAdapter<IMember, TaggedEdge<IMember, EdgeType>> LoadTestGraph()
        {
            TypeMetadataGraphBuilder graphBuilder = new TypeMetadataGraphBuilder();
            graphBuilder.AnalyseAssembly("TestLib", GenerateTestLibAbsolutePath());

            graphBuilder.PrintErrors();

            return graphBuilder.AssemblyGraph;
        }

        public static void AssertTestLibGraphContainsVertex(string fullName)
        {
            IMember vertex = TestLibGraph.Vertices.FirstOrDefault(v => v.FullName.Equals(fullName));
            Assert.IsTrue(vertex != null, "Does not contain vertex " + fullName);
        }

        public static void AssertTestLibGraphContainsEdge(string sourceFullName, string targetFullName, EdgeType edgeType)
        {
            var edge = TestLibGraph.Edges.FirstOrDefault(e => e.Source.FullName.Equals(sourceFullName)
                                                                && e.Target.FullName.Equals(targetFullName)
                                                                && e.Tag.Equals(edgeType));

            AssertTestLibGraphContainsVertex(sourceFullName);
            AssertTestLibGraphContainsVertex(targetFullName);

            Assert.IsTrue(edge != null, String.Format("Could not find edge {0} -{1}-> {2}", sourceFullName, EdgeType.extends, targetFullName));
        }
    }
}
